home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / neogeo.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  36KB  |  1,250 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. Important!  There are two types of NeoGeo romdump - MVS & MGD2.  They are both
  8. converted to a standard format in the vh_start routines.
  9.  
  10.  
  11. Graphics information:
  12.  
  13. 0x00000 - 0xdfff    : Blocks of sprite data, each 0x80 bytes:
  14.     Each 0x80 block is made up of 0x20 double words, their format is:
  15.     Word: Sprite number (16 bits)
  16.     Byte: Palette number (8 bits)
  17.     Byte: Bit 0: X flip
  18.           Bit 1: Y flip
  19.           Bit 2: Automatic animation flag (4 tiles?)
  20.           Bit 3: Automatic animation flag (8 tiles?)
  21.           Bit 4: MSB of sprite number (confirmed, Karnov_r, Mslug). See note.
  22.           Bit 5: MSB of sprite number (MSlug2)
  23.           Bit 6: MSB of sprite number (Kof97)
  24.           Bit 7: Unknown for now
  25.  
  26.     Each double word sprite is drawn directly underneath the previous one,
  27.     based on the starting coordinates.
  28.  
  29. 0x0e000 - 0x0ea00    : Front plane fix tiles (8*8), 2 bytes each
  30.  
  31. 0x10000: Control for sprites banks, arranged in words
  32.  
  33.     Bit 0 to 3 - Y zoom LSB
  34.     Bit 4 to 7 - Y zoom MSB (ie, 1 byte for Y zoom).
  35.     Bit 8 to 11 - X zoom, 0xf is full size (no scale).
  36.     Bit 12 to 15 - Unknown, probably unused
  37.  
  38. 0x10400: Control for sprite banks, arranged in words
  39.  
  40.     Bit 0 to 5: Number of sprites in this bank (see note below).
  41.     Bit 6 - If set, this bank is placed to right of previous bank (same Y-coord).
  42.     Bit 7 to 15 - Y position for sprite bank.
  43.  
  44. 0x10800: Control for sprite banks, arranged in words
  45.     Bit 0 to 5: Unknown
  46.     Bit 7 to 15 - X position for sprite bank.
  47.  
  48. Notes:
  49.  
  50. * If rom set has less than 0x10000 tiles then msb of tile must be ignored
  51. (see Magician Lord).
  52.  
  53. ***************************************************************************/
  54.  
  55. #include "driver.h"
  56. #include "common.h"
  57. #include "usrintrf.h"
  58. #include "vidhrdw/generic.h"
  59.  
  60. //#define NEO_DEBUG
  61.  
  62. static unsigned char *vidram;
  63. static unsigned char *neogeo_paletteram;       /* pointer to 1 of the 2 palette banks */
  64. static unsigned char *pal_bank1;        /* 0x100*16 2 byte palette entries */
  65. static unsigned char *pal_bank2;        /* 0x100*16 2 byte palette entries */
  66. static int palno,modulo,where,high_tile,vhigh_tile,vvhigh_tile;
  67. int no_of_tiles;
  68. static int palette_swap_pending,fix_bank;
  69.  
  70. extern unsigned char *neogeo_ram;
  71. extern unsigned int neogeo_frame_counter;
  72. extern int neogeo_game_fix;
  73.  
  74. void NeoMVSDrawGfx(unsigned char **line,const struct GfxElement *gfx,
  75.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  76.         int zx,int zy,const struct rectangle *clip);
  77.  
  78. static char dda_x_skip[16];
  79. static char dda_y_skip[17];
  80. static char full_y_skip[16]={0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
  81.  
  82. #ifdef NEO_DEBUG
  83.  
  84. int dotiles = 0;
  85. int screen_offs = 0x0000;
  86. int screen_yoffs = 0;
  87.  
  88. #endif
  89.  
  90.  
  91.  
  92. /******************************************************************************/
  93.  
  94. void neogeo_vh_stop(void)
  95. {
  96.        if (pal_bank1) free (pal_bank1);
  97.     if (pal_bank2) free (pal_bank2);
  98.     if (vidram) free (vidram);
  99.     if (neogeo_ram) free (neogeo_ram);
  100.  
  101.     pal_bank1=pal_bank2=vidram=neogeo_ram=0;
  102. }
  103.  
  104. static int common_vh_start(void)
  105. {
  106.     pal_bank1=pal_bank2=vidram=0;
  107.  
  108.     pal_bank1 = malloc(0x2000);
  109.     if (!pal_bank1) {
  110.         neogeo_vh_stop();
  111.         return 1;
  112.     }
  113.  
  114.     pal_bank2 = malloc(0x2000);
  115.     if (!pal_bank2) {
  116.         neogeo_vh_stop();
  117.         return 1;
  118.     }
  119.  
  120.     vidram = malloc(0x20000); /* 0x20000 bytes even though only 0x10c00 is used */
  121.     if (!vidram) {
  122.         neogeo_vh_stop();
  123.         return 1;
  124.     }
  125.     memset(vidram,0,0x20000);
  126.  
  127.     neogeo_paletteram = pal_bank1;
  128.     palno=0;
  129.     modulo=1;
  130.     where=0;
  131.     fix_bank=0;
  132.     palette_swap_pending=0;
  133.  
  134.     return 0;
  135. }
  136.  
  137.  
  138. static void decodetile(int tileno)
  139. {
  140.     unsigned char swap[128];
  141.     UINT32 *gfxdata;
  142.     int x,y;
  143.     unsigned int pen;
  144.  
  145.  
  146.     gfxdata = (UINT32 *)&memory_region(REGION_GFX2)[128 * tileno];
  147.  
  148.     memcpy(swap,gfxdata,128);
  149.  
  150.     for (y = 0;y < 16;y++)
  151.     {
  152.         UINT32 dw;
  153.  
  154.         dw = 0;
  155.         for (x = 0;x < 8;x++)
  156.         {
  157.             pen  = ((swap[64 + 4*y + 3] >> x) & 1) << 3;
  158.             pen |= ((swap[64 + 4*y + 1] >> x) & 1) << 2;
  159.             pen |= ((swap[64 + 4*y + 2] >> x) & 1) << 1;
  160.             pen |=  (swap[64 + 4*y    ] >> x) & 1;
  161.             dw |= pen << 4*(7-x);
  162.             Machine->gfx[2]->pen_usage[tileno] |= (1 << pen);
  163.         }
  164.         *(gfxdata++) = dw;
  165.  
  166.         dw = 0;
  167.         for (x = 0;x < 8;x++)
  168.         {
  169.             pen  = ((swap[4*y + 3] >> x) & 1) << 3;
  170.             pen |= ((swap[4*y + 1] >> x) & 1) << 2;
  171.             pen |= ((swap[4*y + 2] >> x) & 1) << 1;
  172.             pen |=  (swap[4*y    ] >> x) & 1;
  173.             dw |= pen << 4*(7-x);
  174.             Machine->gfx[2]->pen_usage[tileno] |= (1 << pen);
  175.         }
  176.         *(gfxdata++) = dw;
  177.     }
  178. }
  179.  
  180. int neogeo_mvs_vh_start(void)
  181. {
  182.     no_of_tiles=memory_region_length(REGION_GFX2)/128;
  183.     if (no_of_tiles>0x10000) high_tile=1; else high_tile=0;
  184.     if (no_of_tiles>0x20000) vhigh_tile=1; else vhigh_tile=0;
  185.     if (no_of_tiles>0x40000) vvhigh_tile=1; else vvhigh_tile=0;
  186.     Machine->gfx[2]->total_elements = no_of_tiles;
  187.     if (Machine->gfx[2]->pen_usage)
  188.         free(Machine->gfx[2]->pen_usage);
  189.     Machine->gfx[2]->pen_usage = malloc(no_of_tiles * sizeof(int));
  190.     memset(Machine->gfx[2]->pen_usage,0,no_of_tiles * sizeof(int));
  191.  
  192.     /* tiles are not decoded yet. They will be decoded later as they are used. */
  193.     /* pen_usage is used as a marker of decoded tiles: if it is 0, then the tile */
  194.     /* hasn't been decoded yet. */
  195.  
  196.     return common_vh_start();
  197. }
  198.  
  199. /******************************************************************************/
  200.  
  201. static void swap_palettes(void)
  202. {
  203.     int i,newword;
  204.  
  205.     for (i=0; i<0x2000; i+=2)
  206.     {
  207.         int r,g,b;
  208.  
  209.  
  210.            newword = READ_WORD(&neogeo_paletteram[i]);
  211.  
  212.         r = ((newword >> 7) & 0x1e) | ((newword >> 14) & 0x01);
  213.         g = ((newword >> 3) & 0x1e) | ((newword >> 13) & 0x01) ;
  214.         b = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01) ;
  215.  
  216.         r = (r << 3) | (r >> 2);
  217.         g = (g << 3) | (g >> 2);
  218.         b = (b << 3) | (b >> 2);
  219.  
  220.         palette_change_color(i / 2,r,g,b);
  221.     }
  222.  
  223.     palette_swap_pending=0;
  224. }
  225.  
  226. WRITE_HANDLER( neogeo_setpalbank0_w )
  227. {
  228.     if (palno != 0) {
  229.         palno = 0;
  230.         neogeo_paletteram = pal_bank1;
  231.         palette_swap_pending=1;
  232.     }
  233. }
  234.  
  235. WRITE_HANDLER( neogeo_setpalbank1_w )
  236. {
  237.     if (palno != 1) {
  238.         palno = 1;
  239.         neogeo_paletteram = pal_bank2;
  240.         palette_swap_pending=1;
  241.     }
  242. }
  243.  
  244. READ_HANDLER( neogeo_paletteram_r )
  245. {
  246.     return READ_WORD(&neogeo_paletteram[offset]);
  247. }
  248.  
  249. WRITE_HANDLER( neogeo_paletteram_w )
  250. {
  251.     int oldword = READ_WORD (&neogeo_paletteram[offset]);
  252.     int newword = COMBINE_WORD (oldword, data);
  253.     int r,g,b;
  254.  
  255.  
  256.     WRITE_WORD (&neogeo_paletteram[offset], newword);
  257.  
  258.     r = ((newword >> 7) & 0x1e) | ((newword >> 14) & 0x01);
  259.     g = ((newword >> 3) & 0x1e) | ((newword >> 13) & 0x01) ;
  260.     b = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01) ;
  261.  
  262.     r = (r << 3) | (r >> 2);
  263.     g = (g << 3) | (g >> 2);
  264.     b = (b << 3) | (b >> 2);
  265.  
  266.     palette_change_color(offset / 2,r,g,b);
  267. }
  268.  
  269. /******************************************************************************/
  270.  
  271. static const unsigned char *neogeo_palette(const struct rectangle *clip)
  272. {
  273.     int color,code,pal_base,y,my=0,count,offs,i;
  274.      int colmask[256];
  275.     unsigned int *pen_usage; /* Save some struct derefs */
  276.  
  277.     int sx =0,sy =0,oy =0,zx = 1, rzy = 1;
  278.     int tileno,tileatr,t1,t2,t3;
  279.     char fullmode=0;
  280.     int ddax=0,dday=0,rzx=15,yskip=0;
  281.  
  282.     if (Machine->scrbitmap->depth == 16)
  283.     {
  284.         return palette_recalc();
  285.     }
  286.  
  287.     palette_init_used_colors();
  288.  
  289.     /* character foreground */
  290.     pen_usage= Machine->gfx[fix_bank]->pen_usage;
  291.     pal_base = Machine->drv->gfxdecodeinfo[fix_bank].color_codes_start;
  292.     for (color = 0;color < 16;color++) colmask[color] = 0;
  293.     for (offs=0xe000;offs<0xea00;offs+=2) {
  294.         code = READ_WORD( &vidram[offs] );
  295.         color = code >> 12;
  296.         colmask[color] |= pen_usage[code&0xfff];
  297.     }
  298.     for (color = 0;color < 16;color++)
  299.     {
  300.         for (i = 1;i < 16;i++)
  301.         {
  302.             if (colmask[color] & (1 << i))
  303.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_VISIBLE;
  304.         }
  305.     }
  306.  
  307.     /* Tiles */
  308.     pen_usage= Machine->gfx[2]->pen_usage;
  309.     pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
  310.     for (color = 0;color < 256;color++) colmask[color] = 0;
  311.     for (count=0;count<0x300;count+=2) {
  312.         t3 = READ_WORD( &vidram[0x10000 + count] );
  313.         t1 = READ_WORD( &vidram[0x10400 + count] );
  314.         t2 = READ_WORD( &vidram[0x10800 + count] );
  315.  
  316.         /* If this bit is set this new column is placed next to last one */
  317.         if (t1 & 0x40) {
  318.             sx += rzx;
  319.             if ( sx >= 0x1F0 )
  320.                 sx -= 0x200;
  321.  
  322.             /* Get new zoom for this column */
  323.             zx = (t3 >> 8) & 0x0f;
  324.             sy = oy;
  325.         } else {    /* nope it is a new block */
  326.             /* Sprite scaling */
  327.             zx = (t3 >> 8) & 0x0f;
  328.             rzy = t3 & 0xff;
  329.  
  330.             sx = (t2 >> 7);
  331.             if ( sx >= 0x1F0 )
  332.                 sx -= 0x200;
  333.  
  334.             /* Number of tiles in this strip */
  335.             my = t1 & 0x3f;
  336.             if (my == 0x20) fullmode = 1;
  337.             else if (my >= 0x21) fullmode = 2;    /* most games use 0x21, but */
  338.                                                 /* Alpha Mission II uses 0x3f */
  339.             else fullmode = 0;
  340.  
  341.             sy = 0x200 - (t1 >> 7);
  342.             if (clip->max_y - clip->min_y > 8 ||    /* kludge to improve the ssideki games */
  343.                     clip->min_y == Machine->drv->visible_area.min_y)
  344.             {
  345.                 if (sy > 0x110) sy -= 0x200;
  346.                 if (fullmode == 2 || (fullmode == 1 && rzy == 0xff))
  347.                 {
  348.                     while (sy < 0) sy += 2 * (rzy + 1);
  349.                 }
  350.             }
  351.             oy = sy;
  352.  
  353.             if (rzy < 0xff && my < 0x10 && my)
  354.             {
  355.                 my = (my*256)/(rzy+1);
  356.                 if (my > 0x10) my = 0x10;
  357.             }
  358.             if (my > 0x20) my=0x20;
  359.  
  360.             ddax=0;    /* =16; NS990110 neodrift fix */        /* setup x zoom */
  361.         }
  362.  
  363.         /* No point doing anything if tile strip is 0 */
  364.         if (my==0) continue;
  365.  
  366.         /* Process x zoom */
  367.         if(zx!=15) {
  368.             rzx=0;
  369.             for(i=0;i<16;i++) {
  370.                 ddax-=zx+1;
  371.                 if(ddax<=0) {
  372.                     ddax+=15+1;
  373.                     rzx++;
  374.                 }
  375.             }
  376.         }
  377.         else rzx=16;
  378.  
  379.         if(sx>=320) continue;
  380.  
  381.         /* Setup y zoom */
  382.         if(rzy==255)
  383.             yskip=16;
  384.         else
  385.             dday=0;    /* =256; NS990105 mslug fix */
  386.  
  387.         offs = count<<6;
  388.  
  389.         /* my holds the number of tiles in each vertical multisprite block */
  390.         for (y=0; y < my ;y++) {
  391.             tileno  = READ_WORD(&vidram[offs]);
  392.             offs+=2;
  393.             tileatr = READ_WORD(&vidram[offs]);
  394.             offs+=2;
  395.  
  396.             if (high_tile && tileatr&0x10) tileno+=0x10000;
  397.             if (vhigh_tile && tileatr&0x20) tileno+=0x20000;
  398.             if (vvhigh_tile && tileatr&0x40) tileno+=0x40000;
  399.  
  400.             if (tileatr&0x8) tileno=(tileno&~7)+((tileno+neogeo_frame_counter)&7);
  401.             else if (tileatr&0x4) tileno=(tileno&~3)+((tileno+neogeo_frame_counter)&3);
  402.  
  403.             if (fullmode == 2 || (fullmode == 1 && rzy == 0xff))
  404.             {
  405.                 if (sy >= 248) sy -= 2 * (rzy + 1);
  406.             }
  407.             else if (fullmode == 1)
  408.             {
  409.                 if (y == 0x10) sy -= 2 * (rzy + 1);
  410.             }
  411.             else if (sy > 0x110) sy -= 0x200;    /* NS990105 mslug2 fix */
  412.  
  413.             if(rzy!=255) {
  414.                 yskip=0;
  415.                 for(i=0;i<16;i++) {
  416.                     dday-=rzy+1;
  417.                     if(dday<=0) {
  418.                         dday+=256;
  419.                         yskip++;
  420.                     }
  421.                 }
  422.             }
  423.  
  424.             if (sy+yskip-1 >= clip->min_y && sy <= clip->max_y)
  425.             {
  426.                 tileatr=tileatr>>8;
  427.                 tileno %= no_of_tiles;
  428.                 if (pen_usage[tileno] == 0)    /* decode tile if it hasn't been yet */
  429.                     decodetile(tileno);
  430.                 colmask[tileatr] |= pen_usage[tileno];
  431.             }
  432.  
  433.             sy +=yskip;
  434.  
  435.         }  /* for y */
  436.     }  /* for count */
  437.  
  438.     for (color = 0;color < 256;color++)
  439.     {
  440.         for (i = 1;i < 16;i++)
  441.         {
  442.             if (colmask[color] & (1 << i))
  443.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_VISIBLE;
  444.         }
  445.     }
  446.  
  447.     palette_used_colors[4095] = PALETTE_COLOR_VISIBLE;
  448.  
  449.     return palette_recalc();
  450. }
  451.  
  452. /******************************************************************************/
  453.  
  454. WRITE_HANDLER( vidram_offset_w )
  455. {
  456.     where = data;
  457. }
  458.  
  459. READ_HANDLER( vidram_data_r )
  460. {
  461.     return (READ_WORD(&vidram[where << 1]));
  462. }
  463.  
  464. WRITE_HANDLER( vidram_data_w )
  465. {
  466.     WRITE_WORD(&vidram[where << 1],data);
  467.     where = (where + modulo) & 0xffff;
  468. }
  469.  
  470. /* Modulo can become negative , Puzzle Bobble Super Sidekicks and a lot */
  471. /* of other games use this */
  472. WRITE_HANDLER( vidram_modulo_w )
  473. {
  474.     modulo = data;
  475. }
  476.  
  477. READ_HANDLER( vidram_modulo_r )
  478. {
  479.     return modulo;
  480. }
  481.  
  482.  
  483. /* Two routines to enable videoram to be read in debugger */
  484. READ_HANDLER( mish_vid_r )
  485. {
  486.     return READ_WORD(&vidram[offset]);
  487. }
  488.  
  489. WRITE_HANDLER( mish_vid_w )
  490. {
  491.     COMBINE_WORD_MEM(&vidram[offset],data);
  492. }
  493.  
  494. WRITE_HANDLER( neo_board_fix_w )
  495. {
  496.     fix_bank=1;
  497. }
  498.  
  499. WRITE_HANDLER( neo_game_fix_w )
  500. {
  501.     fix_bank=0;
  502. }
  503.  
  504. /******************************************************************************/
  505.  
  506.  
  507. void NeoMVSDrawGfx(unsigned char **line,const struct GfxElement *gfx, /* AJP */
  508.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  509.         int zx,int zy,const struct rectangle *clip)
  510. {
  511.     int /*ox,*/oy,ey,y,dy;
  512.     unsigned char *bm;
  513.     int col;
  514.     int l; /* Line skipping counter */
  515.  
  516.     int mydword;
  517.  
  518.     UINT32 *fspr = (UINT32 *)memory_region(REGION_GFX2);
  519.  
  520.     char *l_y_skip;
  521.  
  522.  
  523.     /* Mish/AJP - Most clipping is done in main loop */
  524.     oy = sy;
  525.       ey = sy + zy -1;     /* Clip for size of zoomed object */
  526.  
  527.     if (sy < clip->min_y) sy = clip->min_y;
  528.     if (ey >= clip->max_y) ey = clip->max_y;
  529.     if (sx <= -16) return;
  530.  
  531.     /* Safety feature */
  532.     code=code%no_of_tiles;
  533.  
  534.     if (gfx->pen_usage[code] == 0)    /* decode tile if it hasn't been yet */
  535.         decodetile(code);
  536.  
  537.     /* Check for total transparency, no need to draw */
  538.     if ((gfx->pen_usage[code] & ~1) == 0)
  539.         return;
  540.  
  541.        if(zy==16)
  542.          l_y_skip=full_y_skip;
  543.     else
  544.          l_y_skip=dda_y_skip;
  545.  
  546.     if (flipy)    /* Y flip */
  547.     {
  548.         dy = -2;
  549.         fspr+=(code+1)*32 - 2 - (sy-oy)*2;
  550.     }
  551.     else        /* normal */
  552.     {
  553.         dy = 2;
  554.         fspr+=code*32 + (sy-oy)*2;
  555.     }
  556.  
  557.     {
  558.         const unsigned short *paldata;    /* ASG 980209 */
  559.         paldata = &gfx->colortable[gfx->color_granularity * color];
  560.         if (flipx)    /* X flip */
  561.         {
  562.             l=0;
  563.             if(zx==16)
  564.             {
  565.                 for (y = sy;y <= ey;y++)
  566.                 {
  567.                     bm  = line[y]+sx;
  568.  
  569.                     fspr+=l_y_skip[l]*dy;
  570.  
  571.                     mydword = fspr[1];
  572.                     col = (mydword>> 0)&0xf; if (col) bm[ 0] = paldata[col];
  573.                     col = (mydword>> 4)&0xf; if (col) bm[ 1] = paldata[col];
  574.                     col = (mydword>> 8)&0xf; if (col) bm[ 2] = paldata[col];
  575.                     col = (mydword>>12)&0xf; if (col) bm[ 3] = paldata[col];
  576.                     col = (mydword>>16)&0xf; if (col) bm[ 4] = paldata[col];
  577.                     col = (mydword>>20)&0xf; if (col) bm[ 5] = paldata[col];
  578.                     col = (mydword>>24)&0xf; if (col) bm[ 6] = paldata[col];
  579.                     col = (mydword>>28)&0xf; if (col) bm[ 7] = paldata[col];
  580.  
  581.                     mydword = fspr[0];
  582.                     col = (mydword>> 0)&0xf; if (col) bm[ 8] = paldata[col];
  583.                     col = (mydword>> 4)&0xf; if (col) bm[ 9] = paldata[col];
  584.                     col = (mydword>> 8)&0xf; if (col) bm[10] = paldata[col];
  585.                     col = (mydword>>12)&0xf; if (col) bm[11] = paldata[col];
  586.                     col = (mydword>>16)&0xf; if (col) bm[12] = paldata[col];
  587.                     col = (mydword>>20)&0xf; if (col) bm[13] = paldata[col];
  588.                     col = (mydword>>24)&0xf; if (col) bm[14] = paldata[col];
  589.                     col = (mydword>>28)&0xf; if (col) bm[15] = paldata[col];
  590.  
  591.                     l++;
  592.                 }
  593.             }
  594.             else
  595.             {
  596.                 for (y = sy;y <= ey;y++)
  597.                 {
  598.                     bm  = line[y]+sx;
  599.                     fspr+=l_y_skip[l]*dy;
  600.  
  601.                     mydword = fspr[1];
  602.                     if (dda_x_skip[ 0]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  603.                     if (dda_x_skip[ 1]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  604.                     if (dda_x_skip[ 2]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  605.                     if (dda_x_skip[ 3]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  606.                     if (dda_x_skip[ 4]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  607.                     if (dda_x_skip[ 5]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  608.                     if (dda_x_skip[ 6]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  609.                     if (dda_x_skip[ 7]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  610.  
  611.                     mydword = fspr[0];
  612.                     if (dda_x_skip[ 8]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  613.                     if (dda_x_skip[ 9]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  614.                     if (dda_x_skip[10]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  615.                     if (dda_x_skip[11]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  616.                     if (dda_x_skip[12]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  617.                     if (dda_x_skip[13]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  618.                     if (dda_x_skip[14]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  619.                     if (dda_x_skip[15]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  620.  
  621.                     l++;
  622.                 }
  623.             }
  624.         }
  625.         else        /* normal */
  626.         {
  627.               l=0;
  628.             if(zx==16)
  629.             {
  630.                 for (y = sy ;y <= ey;y++)
  631.                 {
  632.                     bm  = line[y] + sx;
  633.                     fspr+=l_y_skip[l]*dy;
  634.  
  635.                     mydword = fspr[0];
  636.                     col = (mydword>>28)&0xf; if (col) bm[ 0] = paldata[col];
  637.                     col = (mydword>>24)&0xf; if (col) bm[ 1] = paldata[col];
  638.                     col = (mydword>>20)&0xf; if (col) bm[ 2] = paldata[col];
  639.                     col = (mydword>>16)&0xf; if (col) bm[ 3] = paldata[col];
  640.                     col = (mydword>>12)&0xf; if (col) bm[ 4] = paldata[col];
  641.                     col = (mydword>> 8)&0xf; if (col) bm[ 5] = paldata[col];
  642.                     col = (mydword>> 4)&0xf; if (col) bm[ 6] = paldata[col];
  643.                     col = (mydword>> 0)&0xf; if (col) bm[ 7] = paldata[col];
  644.  
  645.                     mydword = fspr[1];
  646.                     col = (mydword>>28)&0xf; if (col) bm[ 8] = paldata[col];
  647.                     col = (mydword>>24)&0xf; if (col) bm[ 9] = paldata[col];
  648.                     col = (mydword>>20)&0xf; if (col) bm[10] = paldata[col];
  649.                     col = (mydword>>16)&0xf; if (col) bm[11] = paldata[col];
  650.                     col = (mydword>>12)&0xf; if (col) bm[12] = paldata[col];
  651.                     col = (mydword>> 8)&0xf; if (col) bm[13] = paldata[col];
  652.                     col = (mydword>> 4)&0xf; if (col) bm[14] = paldata[col];
  653.                     col = (mydword>> 0)&0xf; if (col) bm[15] = paldata[col];
  654.  
  655.                     l++;
  656.                 }
  657.             }
  658.             else
  659.             {
  660.                 for (y = sy ;y <= ey;y++)
  661.                 {
  662.                     bm  = line[y] + sx;
  663.                     fspr+=l_y_skip[l]*dy;
  664.  
  665.                     mydword = fspr[0];
  666.                     if (dda_x_skip[ 0]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  667.                     if (dda_x_skip[ 1]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  668.                     if (dda_x_skip[ 2]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  669.                     if (dda_x_skip[ 3]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  670.                     if (dda_x_skip[ 4]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  671.                     if (dda_x_skip[ 5]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  672.                     if (dda_x_skip[ 6]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  673.                     if (dda_x_skip[ 7]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  674.  
  675.                     mydword = fspr[1];
  676.                     if (dda_x_skip[ 8]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  677.                     if (dda_x_skip[ 9]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  678.                     if (dda_x_skip[10]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  679.                     if (dda_x_skip[11]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  680.                     if (dda_x_skip[12]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  681.                     if (dda_x_skip[13]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  682.                     if (dda_x_skip[14]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  683.                     if (dda_x_skip[15]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  684.  
  685.                     l++;
  686.                 }
  687.             }
  688.         }
  689.     }
  690. }
  691.  
  692. void NeoMVSDrawGfx16(unsigned char **line,const struct GfxElement *gfx, /* AJP */
  693.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  694.         int zx,int zy,const struct rectangle *clip)
  695. {
  696.     int /*ox,*/oy,ey,y,dy;
  697.     unsigned short *bm;
  698.     int col;
  699.     int l; /* Line skipping counter */
  700.  
  701.     int mydword;
  702.  
  703.     UINT32 *fspr = (UINT32 *)memory_region(REGION_GFX2);
  704.  
  705.     char *l_y_skip;
  706.  
  707.  
  708.     /* Mish/AJP - Most clipping is done in main loop */
  709.     oy = sy;
  710.       ey = sy + zy -1;     /* Clip for size of zoomed object */
  711.  
  712.     if (sy < clip->min_y) sy = clip->min_y;
  713.     if (ey >= clip->max_y) ey = clip->max_y;
  714.     if (sx <= -16) return;
  715.  
  716.     /* Safety feature */
  717.     code=code%no_of_tiles;
  718.  
  719.     if (gfx->pen_usage[code] == 0)    /* decode tile if it hasn't been yet */
  720.         decodetile(code);
  721.  
  722.     /* Check for total transparency, no need to draw */
  723.     if ((gfx->pen_usage[code] & ~1) == 0)
  724.         return;
  725.  
  726.        if(zy==16)
  727.          l_y_skip=full_y_skip;
  728.     else
  729.          l_y_skip=dda_y_skip;
  730.  
  731.     if (flipy)    /* Y flip */
  732.     {
  733.         dy = -2;
  734.         fspr+=(code+1)*32 - 2 - (sy-oy)*2;
  735.     }
  736.     else        /* normal */
  737.     {
  738.         dy = 2;
  739.         fspr+=code*32 + (sy-oy)*2;
  740.     }
  741.  
  742.     {
  743.         const unsigned short *paldata;    /* ASG 980209 */
  744.         paldata = &gfx->colortable[gfx->color_granularity * color];
  745.         if (flipx)    /* X flip */
  746.         {
  747.             l=0;
  748.             if(zx==16)
  749.             {
  750.                 for (y = sy;y <= ey;y++)
  751.                 {
  752.                     bm  = ((unsigned short *)line[y])+sx;
  753.  
  754.                     fspr+=l_y_skip[l]*dy;
  755.  
  756.                     mydword = fspr[1];
  757.                     col = (mydword>> 0)&0xf; if (col) bm[ 0] = paldata[col];
  758.                     col = (mydword>> 4)&0xf; if (col) bm[ 1] = paldata[col];
  759.                     col = (mydword>> 8)&0xf; if (col) bm[ 2] = paldata[col];
  760.                     col = (mydword>>12)&0xf; if (col) bm[ 3] = paldata[col];
  761.                     col = (mydword>>16)&0xf; if (col) bm[ 4] = paldata[col];
  762.                     col = (mydword>>20)&0xf; if (col) bm[ 5] = paldata[col];
  763.                     col = (mydword>>24)&0xf; if (col) bm[ 6] = paldata[col];
  764.                     col = (mydword>>28)&0xf; if (col) bm[ 7] = paldata[col];
  765.  
  766.                     mydword = fspr[0];
  767.                     col = (mydword>> 0)&0xf; if (col) bm[ 8] = paldata[col];
  768.                     col = (mydword>> 4)&0xf; if (col) bm[ 9] = paldata[col];
  769.                     col = (mydword>> 8)&0xf; if (col) bm[10] = paldata[col];
  770.                     col = (mydword>>12)&0xf; if (col) bm[11] = paldata[col];
  771.                     col = (mydword>>16)&0xf; if (col) bm[12] = paldata[col];
  772.                     col = (mydword>>20)&0xf; if (col) bm[13] = paldata[col];
  773.                     col = (mydword>>24)&0xf; if (col) bm[14] = paldata[col];
  774.                     col = (mydword>>28)&0xf; if (col) bm[15] = paldata[col];
  775.  
  776.                     l++;
  777.                 }
  778.             }
  779.             else
  780.             {
  781.                 for (y = sy;y <= ey;y++)
  782.                 {
  783.                     bm  = ((unsigned short *)line[y])+sx;
  784.                     fspr+=l_y_skip[l]*dy;
  785.  
  786.                     mydword = fspr[1];
  787.                     if (dda_x_skip[ 0]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  788.                     if (dda_x_skip[ 1]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  789.                     if (dda_x_skip[ 2]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  790.                     if (dda_x_skip[ 3]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  791.                     if (dda_x_skip[ 4]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  792.                     if (dda_x_skip[ 5]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  793.                     if (dda_x_skip[ 6]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  794.                     if (dda_x_skip[ 7]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  795.  
  796.                     mydword = fspr[0];
  797.                     if (dda_x_skip[ 8]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  798.                     if (dda_x_skip[ 9]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  799.                     if (dda_x_skip[10]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  800.                     if (dda_x_skip[11]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  801.                     if (dda_x_skip[12]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  802.                     if (dda_x_skip[13]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  803.                     if (dda_x_skip[14]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  804.                     if (dda_x_skip[15]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  805.  
  806.                     l++;
  807.                 }
  808.             }
  809.         }
  810.         else        /* normal */
  811.         {
  812.               l=0;
  813.             if(zx==16)
  814.             {
  815.                 for (y = sy ;y <= ey;y++)
  816.                 {
  817.                     bm  = ((unsigned short *)line[y]) + sx;
  818.                     fspr+=l_y_skip[l]*dy;
  819.  
  820.                     mydword = fspr[0];
  821.                     col = (mydword>>28)&0xf; if (col) bm[ 0] = paldata[col];
  822.                     col = (mydword>>24)&0xf; if (col) bm[ 1] = paldata[col];
  823.                     col = (mydword>>20)&0xf; if (col) bm[ 2] = paldata[col];
  824.                     col = (mydword>>16)&0xf; if (col) bm[ 3] = paldata[col];
  825.                     col = (mydword>>12)&0xf; if (col) bm[ 4] = paldata[col];
  826.                     col = (mydword>> 8)&0xf; if (col) bm[ 5] = paldata[col];
  827.                     col = (mydword>> 4)&0xf; if (col) bm[ 6] = paldata[col];
  828.                     col = (mydword>> 0)&0xf; if (col) bm[ 7] = paldata[col];
  829.  
  830.                     mydword = fspr[1];
  831.                     col = (mydword>>28)&0xf; if (col) bm[ 8] = paldata[col];
  832.                     col = (mydword>>24)&0xf; if (col) bm[ 9] = paldata[col];
  833.                     col = (mydword>>20)&0xf; if (col) bm[10] = paldata[col];
  834.                     col = (mydword>>16)&0xf; if (col) bm[11] = paldata[col];
  835.                     col = (mydword>>12)&0xf; if (col) bm[12] = paldata[col];
  836.                     col = (mydword>> 8)&0xf; if (col) bm[13] = paldata[col];
  837.                     col = (mydword>> 4)&0xf; if (col) bm[14] = paldata[col];
  838.                     col = (mydword>> 0)&0xf; if (col) bm[15] = paldata[col];
  839.  
  840.                     l++;
  841.                 }
  842.             }
  843.             else
  844.             {
  845.                 for (y = sy ;y <= ey;y++)
  846.                 {
  847.                     bm  = ((unsigned short *)line[y]) + sx;
  848.                     fspr+=l_y_skip[l]*dy;
  849.  
  850.                     mydword = fspr[0];
  851.                     if (dda_x_skip[ 0]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  852.                     if (dda_x_skip[ 1]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  853.                     if (dda_x_skip[ 2]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  854.                     if (dda_x_skip[ 3]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  855.                     if (dda_x_skip[ 4]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  856.                     if (dda_x_skip[ 5]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  857.                     if (dda_x_skip[ 6]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  858.                     if (dda_x_skip[ 7]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  859.  
  860.                     mydword = fspr[1];
  861.                     if (dda_x_skip[ 8]) { col = (mydword>>28)&0xf; if (col) *bm = paldata[col]; bm++; }
  862.                     if (dda_x_skip[ 9]) { col = (mydword>>24)&0xf; if (col) *bm = paldata[col]; bm++; }
  863.                     if (dda_x_skip[10]) { col = (mydword>>20)&0xf; if (col) *bm = paldata[col]; bm++; }
  864.                     if (dda_x_skip[11]) { col = (mydword>>16)&0xf; if (col) *bm = paldata[col]; bm++; }
  865.                     if (dda_x_skip[12]) { col = (mydword>>12)&0xf; if (col) *bm = paldata[col]; bm++; }
  866.                     if (dda_x_skip[13]) { col = (mydword>> 8)&0xf; if (col) *bm = paldata[col]; bm++; }
  867.                     if (dda_x_skip[14]) { col = (mydword>> 4)&0xf; if (col) *bm = paldata[col]; bm++; }
  868.                     if (dda_x_skip[15]) { col = (mydword>> 0)&0xf; if (col) *bm = paldata[col]; bm++; }
  869.  
  870.                     l++;
  871.                 }
  872.             }
  873.         }
  874.     }
  875. }
  876.  
  877.  
  878.  
  879. /******************************************************************************/
  880.  
  881. static void screenrefresh(struct osd_bitmap *bitmap,const struct rectangle *clip)
  882. {
  883.     int sx =0,sy =0,oy =0,my =0,zx = 1, rzy = 1;
  884.     int offs,i,count,y,x;
  885.     int tileno,tileatr,t1,t2,t3;
  886.     char fullmode=0;
  887.     int ddax=0,dday=0,rzx=15,yskip=0;
  888.     unsigned char **line=bitmap->line;
  889.     unsigned int *pen_usage;
  890.     struct GfxElement *gfx=Machine->gfx[2]; /* Save constant struct dereference */
  891.  
  892.     #ifdef NEO_DEBUG
  893.     char buf[80];
  894.     struct DisplayText dt[2];
  895.  
  896.     /* debug setting, tile view mode connected to '8' */
  897.     if (keyboard_pressed(KEYCODE_8))
  898.     {
  899.         while (keyboard_pressed(KEYCODE_8)) ;
  900.         dotiles ^= 1;
  901.     }
  902.  
  903.     /* tile view - 0x80, connected to '9' */
  904.     if (keyboard_pressed(KEYCODE_9) && !keyboard_pressed(KEYCODE_LSHIFT))
  905.     {
  906.         if (screen_offs > 0)
  907.             screen_offs -= 0x80;
  908.     }
  909.     if (keyboard_pressed(KEYCODE_9) && keyboard_pressed(KEYCODE_LSHIFT))
  910.     {
  911.         if (screen_yoffs > 0)
  912.             screen_yoffs--;
  913.     }
  914.  
  915.     /* tile view + 0x80, connected to '0' */
  916.     if (keyboard_pressed(KEYCODE_0) && !keyboard_pressed(KEYCODE_LSHIFT))
  917.     {
  918.         if (screen_offs < 0x10000)
  919.             screen_offs += 0x80;
  920.     }
  921.     if (keyboard_pressed(KEYCODE_0) && keyboard_pressed(KEYCODE_LSHIFT))
  922.     {
  923.         screen_yoffs++;
  924.     }
  925.     #endif
  926.  
  927.     if (clip->max_y - clip->min_y > 8 ||    /* kludge to speed up raster effects */
  928.             clip->min_y == Machine->drv->visible_area.min_y)
  929.     {
  930.         /* Palette swap occured after last frame but before this one */
  931.         if (palette_swap_pending) swap_palettes();
  932.  
  933.         /* Do compressed palette stuff */
  934.         neogeo_palette(clip);
  935.         /* no need to check the return code since we redraw everything each frame */
  936.     }
  937.  
  938.     fillbitmap(bitmap,Machine->pens[4095],clip);
  939.  
  940. #ifdef NEO_DEBUG
  941. if (!dotiles) {                     /* debug */
  942. #endif
  943.  
  944.     /* Draw sprites */
  945.     for (count=0;count<0x300;count+=2) {
  946.         t3 = READ_WORD( &vidram[0x10000 + count] );
  947.         t1 = READ_WORD( &vidram[0x10400 + count] );
  948.         t2 = READ_WORD( &vidram[0x10800 + count] );
  949.  
  950.         /* If this bit is set this new column is placed next to last one */
  951.         if (t1 & 0x40) {
  952.             sx += rzx;
  953.             if ( sx >= 0x1F0 )
  954.                 sx -= 0x200;
  955.  
  956.             /* Get new zoom for this column */
  957.             zx = (t3 >> 8) & 0x0f;
  958.             sy = oy;
  959.         } else {    /* nope it is a new block */
  960.             /* Sprite scaling */
  961.             zx = (t3 >> 8) & 0x0f;
  962.             rzy = t3 & 0xff;
  963.  
  964.             sx = (t2 >> 7);
  965.             if ( sx >= 0x1F0 )
  966.                 sx -= 0x200;
  967.  
  968.             /* Number of tiles in this strip */
  969.             my = t1 & 0x3f;
  970.             if (my == 0x20) fullmode = 1;
  971.             else if (my >= 0x21) fullmode = 2;    /* most games use 0x21, but */
  972.                                                 /* Alpha Mission II uses 0x3f */
  973.             else fullmode = 0;
  974.  
  975.             sy = 0x200 - (t1 >> 7);
  976.             if (clip->max_y - clip->min_y > 8 ||    /* kludge to improve the ssideki games */
  977.                     clip->min_y == Machine->drv->visible_area.min_y)
  978.             {
  979.                 if (sy > 0x110) sy -= 0x200;
  980.                 if (fullmode == 2 || (fullmode == 1 && rzy == 0xff))
  981.                 {
  982.                     while (sy < 0) sy += 2 * (rzy + 1);
  983.                 }
  984.             }
  985.             oy = sy;
  986.  
  987.             if (rzy < 0xff && my < 0x10 && my)
  988.             {
  989.                 my = (my*256)/(rzy+1);
  990.                 if (my > 0x10) my = 0x10;
  991.             }
  992.             if (my > 0x20) my=0x20;
  993.  
  994.             ddax=0;    /* =16; NS990110 neodrift fix */        /* setup x zoom */
  995.         }
  996.  
  997.         /* No point doing anything if tile strip is 0 */
  998.         if (my==0) continue;
  999.  
  1000.         /* Process x zoom */
  1001.         if(zx!=15) {
  1002.             rzx=0;
  1003.             for(i=0;i<16;i++) {
  1004.                 ddax-=zx+1;
  1005.                 if(ddax<=0) {
  1006.                     ddax+=15+1;
  1007.                     dda_x_skip[i]=1;
  1008.                     rzx++;
  1009.                 }
  1010.                 else dda_x_skip[i]=0;
  1011.             }
  1012.         }
  1013.         else rzx=16;
  1014.  
  1015.         if(sx>=320) continue;
  1016.  
  1017.         /* Setup y zoom */
  1018.         if(rzy==255)
  1019.             yskip=16;
  1020.         else
  1021.             dday=0;    /* =256; NS990105 mslug fix */
  1022.  
  1023.         offs = count<<6;
  1024.  
  1025.         /* my holds the number of tiles in each vertical multisprite block */
  1026.         for (y=0; y < my ;y++) {
  1027.             tileno  = READ_WORD(&vidram[offs]);
  1028.             offs+=2;
  1029.             tileatr = READ_WORD(&vidram[offs]);
  1030.             offs+=2;
  1031.  
  1032.             if (high_tile && tileatr&0x10) tileno+=0x10000;
  1033.             if (vhigh_tile && tileatr&0x20) tileno+=0x20000;
  1034.             if (vvhigh_tile && tileatr&0x40) tileno+=0x40000;
  1035.  
  1036.             if (tileatr&0x8) tileno=(tileno&~7)+((tileno+neogeo_frame_counter)&7);
  1037.             else if (tileatr&0x4) tileno=(tileno&~3)+((tileno+neogeo_frame_counter)&3);
  1038.  
  1039.             if (fullmode == 2 || (fullmode == 1 && rzy == 0xff))
  1040.             {
  1041.                 if (sy >= 248) sy -= 2 * (rzy + 1);
  1042.             }
  1043.             else if (fullmode == 1)
  1044.             {
  1045.                 if (y == 0x10) sy -= 2 * (rzy + 1);
  1046.             }
  1047.             else if (sy > 0x110) sy -= 0x200;    /* NS990105 mslug2 fix */
  1048.  
  1049.             if(rzy!=255)
  1050.             {
  1051.                 yskip=0;
  1052.                 dda_y_skip[0]=0;
  1053.                 for(i=0;i<16;i++)
  1054.                 {
  1055.                     dda_y_skip[i+1]=0;
  1056.                     dday-=rzy+1;
  1057.                     if(dday<=0)
  1058.                     {
  1059.                         dday+=256;
  1060.                         yskip++;
  1061.                         dda_y_skip[yskip]++;
  1062.                     }
  1063.                     else dda_y_skip[yskip]++;
  1064.                 }
  1065.             }
  1066.  
  1067.             if (sy+15 >= clip->min_y && sy <= clip->max_y)
  1068.             {
  1069.                 if (Machine->scrbitmap->depth == 16)
  1070.                     NeoMVSDrawGfx16(line,
  1071.                         gfx,
  1072.                         tileno,
  1073.                         tileatr >> 8,
  1074.                         tileatr & 0x01,tileatr & 0x02,
  1075.                         sx,sy,rzx,yskip,
  1076.                         clip
  1077.                     );
  1078.                 else
  1079.                     NeoMVSDrawGfx(line,
  1080.                         gfx,
  1081.                         tileno,
  1082.                         tileatr >> 8,
  1083.                         tileatr & 0x01,tileatr & 0x02,
  1084.                         sx,sy,rzx,yskip,
  1085.                         clip
  1086.                     );
  1087.             }
  1088.  
  1089.             sy +=yskip;
  1090.         }  /* for y */
  1091.     }  /* for count */
  1092.  
  1093.  
  1094.  
  1095.     /* Save some struct de-refs */
  1096.     gfx=Machine->gfx[fix_bank];
  1097.     pen_usage=gfx->pen_usage;
  1098.  
  1099.     /* Character foreground */
  1100.     for (y=clip->min_y/8; y<=clip->max_y/8; y++) {
  1101.         for (x=0; x<40; x++) {
  1102.  
  1103.               int byte1 = (READ_WORD(&vidram[0xE000 + 2*(y + 32*x)]));
  1104.               int byte2 = byte1 >> 12;
  1105.                byte1 = byte1 & 0xfff;
  1106.  
  1107.             if ((pen_usage[byte1] & ~1) == 0) continue;
  1108.  
  1109.               drawgfx(bitmap,gfx,
  1110.                     byte1,
  1111.                     byte2,
  1112.                     0,0,
  1113.                     x*8,y*8,
  1114.                     clip,TRANSPARENCY_PEN,0);
  1115.           }
  1116.     }
  1117.  
  1118.  
  1119.  
  1120. #ifdef NEO_DEBUG
  1121.     } else {    /* debug */
  1122.         offs = screen_offs;
  1123.         for (y=screen_yoffs;y<screen_yoffs+15;y++) {
  1124.             for (x=0;x<20;x++) {
  1125.                 tileno = READ_WORD(&vidram[offs + 4*y+x*128]);
  1126.                 tileatr = READ_WORD(&vidram[offs + 4*y+x*128+2]);
  1127.  
  1128.                 if (high_tile && tileatr&0x10) tileno+=0x10000;
  1129.                 if (vhigh_tile && tileatr&0x20) tileno+=0x20000;
  1130.                 if (vvhigh_tile && tileatr&0x40) tileno+=0x40000;
  1131.  
  1132.                 if (tileatr&0x8) tileno=(tileno&~7)+((tileno+neogeo_frame_counter)&7);
  1133.                 else if (tileatr&0x4) tileno=(tileno&~3)+((tileno+neogeo_frame_counter)&3);
  1134.  
  1135.                 NeoMVSDrawGfx(line,
  1136.                     Machine->gfx[2],
  1137.                     tileno,
  1138.                     tileatr >> 8,
  1139.                     tileatr & 0x01,tileatr & 0x02,
  1140.                     x*16,(y-screen_yoffs+1)*16,16,16,
  1141.                     &Machine->drv->visible_area
  1142.                  );
  1143.  
  1144.  
  1145.             }
  1146.         }
  1147.  
  1148. {
  1149.     int j;
  1150.     sprintf(buf,"%04X",screen_offs+4*screen_yoffs);
  1151.     for (j = 0;j < 4;j++)
  1152.         drawgfx(bitmap,Machine->uifont,buf[j],UI_COLOR_NORMAL,0,0,3*8+8*j,8*2,0,TRANSPARENCY_NONE,0);
  1153. }
  1154. if (keyboard_pressed(KEYCODE_D))
  1155. {
  1156.     FILE *fp;
  1157.  
  1158.     fp=fopen("video.dmp","wb");
  1159.     if (fp) {
  1160.         fwrite(vidram,0x10c00, 1 ,fp);
  1161.         fclose(fp);
  1162.     }
  1163. }
  1164.     }    /* debug */
  1165. #endif
  1166.  
  1167. #ifdef NEO_DEBUG
  1168. /* More debug stuff :) */
  1169. {
  1170.  
  1171.  
  1172.  
  1173.     int j;
  1174.     char mybuf[20];
  1175.     struct osd_bitmap *mybitmap = Machine->scrbitmap;
  1176.  
  1177.  
  1178.  
  1179.   /*
  1180. for (i = 0;i < 8;i+=2)
  1181. {
  1182.     sprintf(mybuf,"%04X",READ_WORD(&vidram[0x100a0+i]));
  1183.     for (j = 0;j < 4;j++)
  1184.         drawgfx(mybitmap,Machine->uifont,mybuf[j],UI_COLOR_NORMAL,0,0,3*8*i+8*j,8*5,0,TRANSPARENCY_NONE,0);
  1185. }
  1186.  
  1187.  
  1188.     sprintf(mybuf,"%04X",READ_WORD(&vidram[0x10002]));
  1189.     for (j = 0;j < 4;j++)
  1190.         drawgfx(mybitmap,Machine->uifont,mybuf[j],UI_COLOR_NORMAL,0,0,8*j+4*8,8*7,0,TRANSPARENCY_NONE,0);
  1191.     sprintf(mybuf,"%04X",0x200-(READ_WORD(&vidram[0x10402])>>7));
  1192.     for (j = 0;j < 4;j++)
  1193.         drawgfx(mybitmap,Machine->uifont,mybuf[j],UI_COLOR_NORMAL,0,0,8*j+10*8,8*7,0,TRANSPARENCY_NONE,0);
  1194.     sprintf(mybuf,"%04X",READ_WORD(&vidram[0x10802])>> 7);
  1195.     for (j = 0;j < 4;j++)
  1196.         drawgfx(mybitmap,Machine->uifont,mybuf[j],UI_COLOR_NORMAL,0,0,8*j+16*8,8*7,0,TRANSPARENCY_NONE,0);
  1197.  
  1198. */
  1199.  
  1200.  
  1201. //        logerror("X: %04x Y: %04x Video: %04x\n",READ_WORD(&vidram[0x1089c]),READ_WORD(&vidram[0x1049c]),READ_WORD(&vidram[0x1009c]));
  1202.  
  1203. //logerror("X: %04x Y: %04x Video: %04x\n",READ_WORD(&vidram[0x10930]),READ_WORD(&vidram[0x10530]),READ_WORD(&vidram[0x10130]));
  1204.  
  1205.  
  1206. }
  1207. #endif
  1208.  
  1209. }
  1210.  
  1211. void neogeo_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1212. {
  1213.     screenrefresh(bitmap,&Machine->drv->visible_area);
  1214. }
  1215.  
  1216. static int next_update_first_line;
  1217.  
  1218. void neogeo_vh_raster_partial_refresh(struct osd_bitmap *bitmap,int current_line)
  1219. {
  1220.     struct rectangle clip;
  1221.  
  1222.     if (current_line < next_update_first_line)
  1223.         next_update_first_line = 0;
  1224.  
  1225.     clip.min_x = Machine->drv->visible_area.min_x;
  1226.     clip.max_x = Machine->drv->visible_area.max_x;
  1227.     clip.min_y = next_update_first_line;
  1228.     clip.max_y = current_line;
  1229.     if (clip.min_y < Machine->drv->visible_area.min_y)
  1230.         clip.min_y = Machine->drv->visible_area.min_y;
  1231.     if (clip.max_y > Machine->drv->visible_area.max_y)
  1232.         clip.max_y = Machine->drv->visible_area.max_y;
  1233.  
  1234.     if (clip.max_y >= clip.min_y)
  1235.     {
  1236. //logerror("refresh %d-%d\n",clip.min_y,clip.max_y);
  1237.         screenrefresh(bitmap,&clip);
  1238.     }
  1239.  
  1240.     next_update_first_line = current_line + 1;
  1241. }
  1242.  
  1243. void neogeo_vh_raster_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1244. {
  1245.     /* Palette swap occured after last frame but before this one */
  1246.     if (palette_swap_pending) swap_palettes();
  1247.     palette_recalc();
  1248.     /* no need to check the return code since we redraw everything each frame */
  1249. }
  1250.